#include "../easyunit/test.h"
#include "../source/factory/Factory.h"

using namespace easyunit;

DECLARE(Node)
	Factory* f;
	Graph *g1, *g2, *g3, *g4, *g5;
	Node *n1, *n2, *n3, *n4, *n5;
END_DECLARE

SETUP(Node)
{
	f = Factory::getInstance();
	g1 = f->createGraph(10, 1);
	g2 = f->createGraph(0, 0);
	g3 = f->createGraph(1, 1);
	g4 = f->createGraph(10, 0.5);
	g5 = f->createGraph(2, 0);
	n1 = new Node(1);
	n2 = new Node(2);
	n3 = new Node(3);
	n4 = new Node(4);
	n5 = new Node();
}

TEARDOWN(Node)
{
}

TESTF(Node, constructors)
{
	ASSERT_TRUE(n1->getEdgeList() != NULL);
	ASSERT_TRUE(n2->getEdgeList() != NULL);
	ASSERT_TRUE(n1->getID() == 1);
	ASSERT_TRUE(n2->getID() == 2);
	ASSERT_TRUE(n5->getID() != 0);
}

TESTF(Node, setID_and_getID)
{
	ASSERT_TRUE(n1->getID() == 1);
	ASSERT_TRUE(n2->getID() == 2);
	ASSERT_TRUE(n3->getID() == 3);
	ASSERT_TRUE(n4->getID() == 4);

	n1->setID(2);
	ASSERT_TRUE(n1->getID() == 2);

	n2->setID(12);
	ASSERT_TRUE(n2->getID() == 12);

	n3->setID(14);
	ASSERT_TRUE(n3->getID() == 14);

	n4->setID(0);
	ASSERT_TRUE(n4->getID() == 4);
}

TESTF(Node, equal)
{
	ASSERT_TRUE((*n1 == *n2) == false);
	n2->setID(1);
	ASSERT_TRUE(*n1 == *n2);
	ASSERT_TRUE(*n2 == *n2);
	ASSERT_TRUE(*n2 == *n1);
	ASSERT_TRUE(*n3 == *n3);
	ASSERT_TRUE((*n1 == *n3) == false);
}

TESTF(Node, different)
{
	ASSERT_TRUE((*n1 != *n2));
	n2->setID(1);
	ASSERT_TRUE((*n1 != *n2) == false);
	ASSERT_TRUE((*n2 != *n2) == false);
	ASSERT_TRUE(*n2 != *n4);
	ASSERT_TRUE((*n1 != *n5) == false);
	ASSERT_TRUE(*n3 != *n5);
	ASSERT_TRUE(*n1 != *n3);
}

TESTF(Node, lessThan)
{
	ASSERT_TRUE((*n1 < *n2));
	n2->setID(1);
	ASSERT_TRUE((*n1 < *n2) == false);
	ASSERT_TRUE((*n2 < *n2) == false);
	ASSERT_TRUE((*n1 < *n3));
	ASSERT_TRUE((*n4 < *n3) == false);
	ASSERT_TRUE((*n1 < *n4));
}

TESTF(Node, addEdge)
{
	g1->nodeAt(0)->addEdge(g1->nodeAt(0));
	g1->nodeAt(0)->addEdge(g1->nodeAt(1));
	ASSERT_TRUE(g1->numberOfEdge() == 45);

	g5->nodeAt(0)->addEdge(g5->nodeAt(1));
	ASSERT_TRUE(g5->nodeAt(0)->hasEdgeWith(g5->nodeAt(1)));
	ASSERT_TRUE(g5->numberOfEdge() == 1);
}

TESTF(Node, isRoot)
{
	ASSERT_TRUE(n1->isRoot() == true);
	ASSERT_TRUE(n2->isRoot() == false);
	ASSERT_TRUE(n3->isRoot() == false);
	ASSERT_TRUE(n4->isRoot() == false);
}

TESTF(Node, isLeaf)
{
	ASSERT_TRUE(n1->isLeaf() == false);

	ASSERT_TRUE(g5->nodeAt(0)->isLeaf() == false);
	ASSERT_TRUE(g5->nodeAt(1)->isLeaf() == false);
	g5->createEdge(g5->nodeAt(0), g5->nodeAt(1));
	ASSERT_TRUE(g5->nodeAt(0)->isLeaf() == true);
	ASSERT_TRUE(g5->nodeAt(1)->isLeaf() == true);
}

TESTF(Node, outDeg)
{
	ASSERT_TRUE(g1->nodeAt(0)->outDeg() == 9)
	g1->eraseEdgesOfNode(g1->nodeAt(0));
	ASSERT_TRUE(g1->nodeAt(1)->outDeg() == 8)
}

TESTF(Node, hasEdgeWith)
{
	
	ASSERT_TRUE(g1->nodeAt(0)->hasEdgeWith(g1->nodeAt(0)) == false)
	ASSERT_TRUE(g1->nodeAt(1)->hasEdgeWith(g1->nodeAt(1)) == false)
	ASSERT_TRUE(g1->nodeAt(0)->hasEdgeWith(g1->nodeAt(1)) == true)
	ASSERT_TRUE(g1->nodeAt(1)->hasEdgeWith(g1->nodeAt(0)) == true)
	ASSERT_TRUE(g1->nodeAt(0)->hasEdgeWith(g1->nodeAt(7)) == true)
	ASSERT_TRUE(g1->nodeAt(4)->hasEdgeWith(g1->nodeAt(9)) == true)

	ASSERT_TRUE(g3->nodeAt(0)->hasEdgeWith(g3->nodeAt(0)) == false)
	g3->addNode(n1);
	g3->addNode(n2);
	ASSERT_TRUE(g3->nodeAt(0)->hasEdgeWith(g3->nodeAt(1)) == false);
	g3->nodeAt(0)->addEdge(g3->nodeAt(1));
	ASSERT_TRUE(g3->nodeAt(0)->hasEdgeWith(g3->nodeAt(1)) == true);

	ASSERT_TRUE(g4->nodeAt(0)->hasEdgeWith(g4->nodeAt(0)) == false)
	ASSERT_TRUE(g4->nodeAt(5)->hasEdgeWith(g4->nodeAt(5)) == false)

	ASSERT_TRUE(g5->nodeAt(0)->hasEdgeWith(g5->nodeAt(1)) == false)
	g5->addNode(n3);
	g5->addNode(n4);
	ASSERT_TRUE(g5->nodeAt(0)->hasEdgeWith(g5->nodeAt(1)) == false);
	g5->nodeAt(0)->addEdge(g5->nodeAt(1));
	g5->nodeAt(2)->addEdge(g5->nodeAt(2));
	ASSERT_TRUE(g5->nodeAt(0)->hasEdgeWith(g5->nodeAt(1)) == true);
	ASSERT_TRUE(g5->nodeAt(2)->hasEdgeWith(g5->nodeAt(2)) == false);
}


